package main;


import java.awt.Color;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;

import javax.swing.*;

import java.awt.event.*;
import java.io.File;
import java.util.ArrayList;

import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.swing.plaf.basic.BasicTabbedPaneUI;
import javax.swing.UIManager.LookAndFeelInfo;

import org.jfugue.midi.MidiFileManager;
import org.jfugue.pattern.Pattern;

public class ui extends JFrame{
	static Color defaultColor = Color.BLACK;
	static Color currentbuttoncolor = Color.green;
	static boolean mousepressed=false;
	private static boolean syncOn=true;
	//public boolean clickmenu = false;
	static ArrayList<MusicThreads> music= new ArrayList<MusicThreads>();
	static ArrayList<JComboBox> instrumentList = new ArrayList<JComboBox>();
	static ArrayList<Thread> threads=new ArrayList<Thread>();
	//add for tabbed play
	JTextField text;
	JTextField volume;
	public JCheckBox checkbox;
	// keeps reference of all buttons
	static ArrayList<ArrayList<JButton>> buttons =new ArrayList<ArrayList<JButton>>();
	static JTabbedPane tabbedpanel;
	public static ArrayList<ArrayList<Integer>> textinput =new ArrayList<ArrayList<Integer>>();
	//static ui UI=new ui();
	
	public ui(){
		
		super("Music Composer");
		
		/*Structure of UI
		 *Frame(MainFrame)
		 *	Panel_pane(MainPane) 	
		 *   	Panel_p(TopPanel)
		 *   		ComboBox*4_newList(ComboBox0-3)
		 *   	TabbedPane_tabbedpanel(TabbedPane)
		 *   		TabbedPane1(MuTabbedPane1)
		 *   			RoundButton
		 *   		TabbedPane2(MuTabbedPane2)
		 *   			RoundButton
		 *   		...
		 *   	Panel_p3(BottomPanel)
		 *   		Menu (FunctionMenu)+ Button (FunctionButton + function_name)
		 *   
		 *Structure of Menu
		 *  Menu(FunctionMenu)
		 *  	menu_clearmenu(ClearMenu)
		 *  		item1_clearsub1(ClearThisLayer)
		 *  		item2_clearsub2(ClearAllLayers)
		 *  	menuitem_random(Random)
		 * 
		 */
		Container root = getContentPane();
		//root.setLayout(new BoxLayout(root, BoxLayout.X_AXIS));
		root.setVisible(true);
		
		
		JPanel pane = new JPanel();
		pane.setLayout( new BoxLayout(pane,BoxLayout.Y_AXIS));
		pane.setBackground(defaultColor);
		pane.setPreferredSize(new Dimension(660, 780));
		pane.setName("MainPane"); //for test case
		getContentPane().add(pane);
		GridBagConstraints c = new GridBagConstraints();
		 
			
			//Start adding 6 combo box
			JPanel p = new JPanel();
			p.setBackground(defaultColor);
			p.setLayout(new GridBagLayout());
			p.setName("TopPanel");  //for test case
			
			pane.add(p);
			
			createTopComboBox(c, p);
			//Finish adding 6 combo box
			
			//Start creating Tabs
			tabbedpanel = new JTabbedPane();
			tabbedpanel.addChangeListener(new TabChangeListener());
			tabbedpanel.setName("TabbedPane");
			
			createTabsMusicPanel(c, pane, tabbedpanel);
			//Finish creating tabs
			
			//start adding function menu
			JPanel p3 = new JPanel();
			p3.setLayout(new GridBagLayout());
			p3.setName("BottomPanel"); //for test case
			pane.add(p3);

			JMenu menu = new JMenu("Functions");
			menu.setName("FunctionMenu"); //for test case
			menu.setForeground(Color.BLACK);
			//menu.setBackground(Color.BLACK);
			c.fill=GridBagConstraints.HORIZONTAL;
			c.gridx=0;
			c.gridy=0;
			c.weightx=0.5;
			JMenu clearmenu = new JMenu("Clear");
			clearmenu.setName("ClearMenu"); //for test case

			
			JMenuItem clearsub1 = new JMenuItem("All Notes On This Layer");
			clearsub1.setName("ClearThisLayer"); //for test case
			clearsub1.addActionListener(new ActionListener(){
				@Override
				public void actionPerformed(ActionEvent e) {
					music.get(MusicThreads.currentTab).clickmenu = true;
					music.get(MusicThreads.currentTab).clear=true;
					for(int j=0;j<buttons.get(MusicThreads.currentTab).size();j++){
						buttons.get(MusicThreads.currentTab).get(j).setBackground(Color.DARK_GRAY);
		
					}
				}			
			});
			
			JMenuItem clearsub2 = new JMenuItem("All Notes On All Layer");
			clearsub2.setName("ClearAllLayers"); //for test case
			clearsub2.addActionListener(new ActionListener(){
				@Override
				public void actionPerformed(ActionEvent arg0) {
					music.get(MusicThreads.currentTab).clickmenu = true;
					
					for(int k=0;k<music.size();k++) {
						music.get(k).clear=true;
					
						for(int i=0;i<buttons.size();i++){
							for(int j=0;j<buttons.get(i).size();j++){
								//if(music.get(k).block.get(i).get(j)!= -1){
								buttons.get(i).get(j).setBackground(Color.DARK_GRAY);
								//music.get(k).block.get(i).set(j, -1);
								
								
								//}
							
							}
						}
					}
					
					/*for(int i=0;i<music.size();i++) music.get(i).clear=true;
					
					for(int i=0;i<buttons.size();i++){
						for(int j=0;j<buttons.get(i).size();j++){
							buttons.get(i).get(j).setBackground(Color.DARK_GRAY);
							
						}
					}*/
				}
				
			});
			
			clearmenu.add(clearsub1);
			clearmenu.add(clearsub2);
			
			menu.add(clearmenu);
			
			JMenu shiftmenu = new JMenu("Shift");
			shiftmenu.setName("Shift"); //for test case
			
			JMenu shiftone = new JMenu("Shift This Layer");
			JMenuItem sholeft = new JMenuItem("Left");
			sholeft.setName("ShiftOneLeft");// for test case
			sholeft.addActionListener(new ShiftOneLeftListener());
			JMenuItem shoright = new JMenuItem("Right");
			shoright.setName("ShiftOneRight"); //for test case
			shoright.addActionListener(new ShiftOneRightListener());
			//shoright.addMouseListener(new ShiftOneRightListener());
			JMenuItem shoup = new JMenuItem("Up");
			shoup.setName("ShiftOneUp"); // for test case
			shoup.addActionListener(new ShiftOneUpListener());
			JMenuItem shodown = new JMenuItem("Down");
			shodown.setName("ShiftOneDown"); // for test case
			shodown.addActionListener(new ShiftOneDownListener());
			
			shiftone.add(sholeft);
			shiftone.add(shoright);
			shiftone.add(shoup);
			shiftone.add(shodown);
			
			shiftmenu.add(shiftone);
			
			JMenu shiftall = new JMenu("Shift All Layers");
			JMenuItem shaleft = new JMenuItem("Left");
			shaleft.setName("ShiftAllLeft");
			shaleft.addActionListener(new ShiftAllLeftListener());
			JMenuItem sharight = new JMenuItem("Right");
			sharight.setName("ShiftAllRight");
			sharight.addActionListener(new ShiftAllRightListener());
			JMenuItem shaup = new JMenuItem("Up");
			shaup.setName("ShiftAllUp");
			shaup.addActionListener(new ShiftAllUpListener());
			JMenuItem shadown = new JMenuItem("Down");
			shadown.setName("ShiftAllDown");
			shadown.addActionListener(new ShiftAllDownListener());
			
			shiftall.add(shaleft);
			shiftall.add(sharight);
			shiftall.add(shaup);
			shiftall.add(shadown);
			
			shiftmenu.add(shiftall);
			
			menu.add(shiftmenu);
			
			JMenu buttoncolorchange = new JMenu("Change Button Color");
			menu.add(buttoncolorchange);//CYAN,BLUE, PINK, RED, YELLOW
			JMenuItem cyan = new JMenuItem("Cyan");
			buttoncolorchange.add(cyan);
			cyan.setName("cyan");
			cyan.addActionListener(new ButtonCyanChangeListener());
			JMenuItem blue = new JMenuItem("Blue");
			buttoncolorchange.add(blue);
			blue.setName("blue");
			blue.addActionListener(new ButtonBlueChangeListener());
			JMenuItem pink = new JMenuItem("Pink");
			buttoncolorchange.add(pink);
			pink.setName("pink");
			pink.addActionListener(new ButtonPinkChangeListener());
			JMenuItem red = new JMenuItem("Red");
			buttoncolorchange.add(red);
			red.setName("red");
			red.addActionListener(new ButtonRedChangeListener());
			JMenuItem yellow = new JMenuItem("Yellow");
			buttoncolorchange.add(yellow);
			yellow.setName("yellow");
			yellow.addActionListener(new ButtonYellowChangeListener());
			
			JMenuItem saveasmidi = new JMenuItem("Save As MIDI");
			menu.add(saveasmidi);
			saveasmidi.setName("Save");
			saveasmidi.addActionListener(new saveMidiListener());
			
			JMenuItem help = new JMenuItem("Help");
			menu.add(help);
			help.setName("Help");
			help.addActionListener(new HelpListener());
			
			//panel 3 starts here
			
			JMenuBar menuBar = new JMenuBar();
	        menuBar.add(menu);
			p3.add(menuBar);
			p3.setBackground(defaultColor);
			//finish adding function menu
			c.fill=GridBagConstraints.HORIZONTAL;
			
			//for inputting text, e.g. 1,2;3,4 means tab 1 and 2 play together, then stop, and tab 3 and 4 play together
			
			//making space
			JLabel label = new JLabel(" ");
			//label.setForeground(Color.WHITE);
			label.setPreferredSize(new Dimension(50,23));
			c.gridx=0;
			c.gridy=0;
			p3.add(label,c);
			
			label = new JLabel("Volume(max120): ");
			//label.setForeground(Color.WHITE);
			label.setOpaque(true);
			label.setBackground(Color.WHITE);
			label.setPreferredSize(new Dimension(100,23));
			c.gridx=1;
			c.gridy=0;
			p3.add(label,c);
			
			volume = new JTextField("");
			volume.setPreferredSize(new Dimension(50,23));
			c.gridx=2;
			c.gridy=0;
			p3.add(volume,c);
			
			JButton Vbutton=new JButton("ok");
			Vbutton.addActionListener(new VButtonListener());
			Vbutton.setName("Vbutton" ); //for test case
			c.gridx=3;
			c.gridy=0;
			c.weightx=0.5;
			Vbutton.setPreferredSize(new Dimension(30,23));
			p3.add(Vbutton,c);
			
			
			label = new JLabel("Tab Mode: ");
			//label.setForeground(Color.WHITE);
			label.setOpaque(true);
			label.setBackground(Color.WHITE);
			label.setPreferredSize(new Dimension(80,23));
			c.gridx=4;
			c.gridy=0;
			p3.add(label,c);
			
			text = new JTextField();
			text.setPreferredSize(new Dimension(100,23));
			c.gridx=5;
			c.gridy=0;
			p3.add(text,c);
			
			JButton Ibutton=new JButton("ok");
			Ibutton.addActionListener(new IButtonListener());
			Ibutton.setName("Ibutton" ); //for test case
			c.gridx=6;
			c.gridy=0;
			c.weightx=0.5;
			Ibutton.setPreferredSize(new Dimension(30,23));
			p3.add(Ibutton,c);
			
			/*JLabel label = new JLabel("Tab Mode: ");
			label.setForeground(Color.WHITE);
			c.gridx=7;
			c.gridy=0;
			p3.add(label);*/
			checkbox = new JCheckBox();
			c.gridx=8;
			p3.add(checkbox,c);
			
				
		pack();
	}
	public class ButtonCyanChangeListener implements ActionListener{
		@Override
		public void actionPerformed(ActionEvent e){
			music.get(MusicThreads.currentTab).clickmenu = true;
			ColorChange(Color.cyan);
			currentbuttoncolor = Color.cyan;
		}
		
	}
	
	public class ButtonBlueChangeListener implements ActionListener{
		@Override
		public void actionPerformed(ActionEvent e){
			music.get(MusicThreads.currentTab).clickmenu = true;
			ColorChange(Color.blue);
			currentbuttoncolor = Color.blue;
		}
		
	}
	
	public class ButtonPinkChangeListener implements ActionListener{
		@Override
		public void actionPerformed(ActionEvent e){
			music.get(MusicThreads.currentTab).clickmenu = true;
			ColorChange(Color.pink);
			currentbuttoncolor = Color.pink;
		}
		
	}
	
	public class ButtonRedChangeListener implements ActionListener{
		@Override
		public void actionPerformed(ActionEvent e){
			music.get(MusicThreads.currentTab).clickmenu = true;
			ColorChange(Color.red);
			currentbuttoncolor = Color.red;
		}
		
	}
	
	public class ButtonYellowChangeListener implements ActionListener{
		@Override
		public void actionPerformed(ActionEvent e){
			music.get(MusicThreads.currentTab).clickmenu = true;
			ColorChange(Color.yellow);
			currentbuttoncolor = Color.yellow;
		}
		
	}
	
	public class HelpListener implements ActionListener{
		private HelpListener(){};
		@Override
		public void actionPerformed(ActionEvent e){
			music.get(MusicThreads.currentTab).clickmenu = true;
			String txt = "Please use the top combo boxes to adjust instructments. \n" +
					"By selecting the tab, you can edit notes of different layers. \n" +
					"Input a volume in a number between 0 to 120, and click ok to change volume. \n" +
					"Tabbed mode is to play notes in a special format. Player will play according to your input. \n" +
					"By inputting\" 0,1; \" The first two tab will play together. \n" +
					"By inputting \"0;1,2;\",the first tab will play, follow by the second and third tab playing together. \n" +
					"After input, click ok to confirm your change. \n" +
					"Then please check the check box beside to apply the tabbed mode" +
					"Investigate and create you own piece of music! ";
			JOptionPane.showMessageDialog(null, txt, "Help", JOptionPane.INFORMATION_MESSAGE);
		}
	}
	public static void main(String[] args){
		/*JFrame frame = new JFrame("Music Composer");
		frame.setName("MainFrame"); //for test case
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		MusicThreads.UI=UI;
		UI.addComponentsToPane(frame.getContentPane());
		frame.pack();
		frame.setVisible(true);
		MusicThreads m;
		//create new music threads
		createMusicThreads();*/
		ui UI = new ui();
		UI.show();
		UI.setDefaultCloseOperation(EXIT_ON_CLOSE);
		MusicThreads.UI = UI;
		MusicThreads m;
		createMusicThreads();
		
	}

	private static void createMusicThreads() {
		MusicThreads m;
		for(int i = 0 ; i < 6 ; i++){
			m=new MusicThreads(instrumentList.get(i),i);
			//System.out.println("combo box index" + instrumentList.get(i).getClientProperty("tab"));
			music.add(m);
			threads.add(new Thread(m));	
		}
		for ( int z = 0; z<6 ; z++){
			threads.get(z).start();
		}
	}
	
	
	private void createTabsMusicPanel(GridBagConstraints c, JPanel p, JTabbedPane tabp){
		
		for(int i = 1 ; i < 7 ; i++){
			JPanel p2=new JPanel();
			p2.setLayout(new GridLayout(16, 16));
			p2.setName("MuTabbedPane" + i); //for test case
			tabbedpanel.addTab("Tab"+i, p2);
			ArrayList<JButton> tmp=new ArrayList<JButton>();
			//start adding music panel
			addMusicPanel16_16(c, i, p2, tmp);
			buttons.add(tmp);
			//finish adding music panel

		}
		p.add(tabp);
		
		
	}

	private void addMusicPanel16_16(GridBagConstraints c, int i, JPanel p2,
			ArrayList<JButton> tmp) {
		for(int y = 0 ;  y<16 ; y=y+1){
			for(int x = 0 ;  x<16 ; x=x+1){
				//JButton button =new JButton();
				RoundedCornerButton button = new RoundedCornerButton();
				button.setName("button"+y+x); //for test case
				tmp.add(button);
				button.setFocusable(false);
				button.setRolloverEnabled(false);
				button.setBorderPainted(false); 
				button.setPreferredSize(new Dimension(37,37));
				button.putClientProperty("column", new Integer(x));
				button.putClientProperty("row", new Integer(15-y));
				button.putClientProperty("tab", new Integer(i-1));
				button.addMouseListener(new MousePressedListener());
				button.setBackground(Color.DARK_GRAY);
				c.fill=GridBagConstraints.HORIZONTAL;
				c.gridx=x;
				c.gridy=y+1;
				c.ipadx=3;
				c.ipady=3;
				//c.weightx=0.1;
				//c.gridwidth=1;
				p2.add(button,c);
				p2.setBackground(defaultColor);
			}
		}
	}


	private void createTopComboBox(GridBagConstraints c, JPanel p) {
		
		String[] InstrumentList = { " ", "Piano","Violin","Drum","Ovdn. Guitar","Elec Jazz Guitar","Vibraphone","Music Box","Trumpet","Flute","Soprano Sax","Church Organ","French Horn","Clarinet","Bird Tweet","Whistle","Pad New Age" };
		
		for(int x = 0 ;  x<6 ; x++){
			JComboBox newList =new JComboBox(InstrumentList);
			newList.setName("ComboBox" + x); //for test case
			instrumentList.add(newList);
			instrumentList.get(x).setSelectedIndex(0);
			instrumentList.get(x).putClientProperty("tab",x);
			c.fill=GridBagConstraints.HORIZONTAL;
			c.gridx=x;
			c.gridy=0;
			c.weightx=0.5;
			c.gridwidth=1;
			p.add(instrumentList.get(x),c);
		}
	}
	public static boolean EditNote(int col,int row,boolean on,int tab){
//		System.out.println("col "+col+" row "+ row + " tab " + tab);
		String[] note;
		int numofNotes;
//		System.out.println("list instrument index" + instrumentList.get(tab).getSelectedIndex());
//		System.out.println("list tab" + instrumentList.get(tab).getClientProperty("tab"));
		if(instrumentList.get(tab).getSelectedIndex()==3){
			note=music.get(tab).drumnotes;
//			numofNotes=music.drumnotes.length;
		}
		else{
			note=music.get(tab).notes;
//			numofNotes=music.notes.length;
		}
//		row=row%numofNotes;
		if(!on){
			if(music.get(tab).block.get(col).get(0)==-1) music.get(tab).block.get(col).set(0,row);
			else  music.get(tab).block.get(col).add(row);
		}else if(on){
			if(music.get(tab).block.get(col).size()==1) music.get(tab).block.get(col).set(0,-1);
			else{
				for(int i=0;i<music.get(tab).block.get(col).size();i++){
					if(music.get(tab).block.get(col).get(i).equals(row)){
						music.get(tab).block.get(col).remove(i);
						break;
					}
				}
			}
		}
		return !on;
		
	}
	
	public class saveMidiListener implements ActionListener{
		
		String[] notes={"D4","E4","F4","G4","A4","B4","C5","D5","E5","F5","G5","A5","B5","C6","D6","E6"};
		
		@Override
		public void actionPerformed(ActionEvent arg0) {
			music.get(MusicThreads.currentTab).clickmenu = true;
			String[] patterns={"","","","","",""};
			if(!checkbox.isSelected()){
				for(int i=0;i<6;i++){
					parseToString(patterns,i);  // repeat 3 times in repeat mode
					parseToString(patterns,i);
					parseToString(patterns,i);
				}
			}else{
				for(int i=0;i<textinput.size();i++){
					boolean[] parsed={false,false,false,false};
					for(int j=0;j<textinput.get(i).size();j++){
						parseToString(patterns,textinput.get(i).get(j));
						parsed[textinput.get(i).get(j)]=true;
					}
					for(int k=0;k<6;k++) System.out.println(parsed[k]);
					for(int j=0;j<6;j++){
						if(!parsed[j]){
							System.out.println("in2");
							if(music.get(j).instrument!=-1) // if instrument is not drums
								patterns[j]=patterns[j]+" T240 V"+j+" I"+music.get(j).instrument+" Ri Ri Ri Ri Ri Ri Ri Ri Ri Ri Ri Ri Ri Ri Ri Ri";
							else
								patterns[j]=patterns[j]+" T240 V9 Ri Ri Ri Ri Ri Ri Ri Ri Ri Ri Ri Ri Ri Ri Ri Ri";
						}
					}
				}
			}
			for(int i=0;i<6;i++){
				System.out.println("For i="+i);
				System.out.println(patterns[i]);
			}
			Pattern[] tracks=new Pattern[6];
			Pattern song=new Pattern();
			for(int i=0;i<6;i++){
				tracks[i]=new Pattern(patterns[i]);
				song.add(tracks[i]);
			}
			try {  // save to midi
                MidiFileManager.savePatternToMidi(song,new File("music.mid"));
			} catch (Exception e) {
                e.printStackTrace();
			}	
		}
		
		public void parseToString(String[] patterns,int i){
			if(music.get(i).instrument!=-1)
				patterns[i]=patterns[i]+" T240 "+"V"+i+" I"+music.get(i).instrument;
			else
				patterns[i]=patterns[i]+" T240 V9";
			
			ArrayList<ArrayList<Integer>> temp=music.get(i).block;
			for(int j=0;j<temp.size();j++){
				patterns[i]=patterns[i]+" ";
				int col=0;
				int k;
				String duration="";
				if(temp.get(j).get(0)!=-1){
					int len=1;
					col=j+len;
					for(;len<4;len++,col++){					
						if(col==16) col=0;
						if(temp.get(col).get(0)!=-1) break;
					}
					duration=duration(len);
				}
				for(k=0;k<temp.get(j).size();k++){					
					if(temp.get(j).get(0)==-1) patterns[i]=patterns[i]+"Ri";
					else if(music.get(i).instrument!=-1){
						patterns[i]=patterns[i]+notes[temp.get(j).get(k)]+duration;
						if(k!=temp.get(j).size()-1) patterns[i]=patterns[i]+"+";
					}else{
						int inst=temp.get(j).get(k)%2;
						if(inst==0) patterns[i]=patterns[i]+"[BASS_DRUM]"+duration;
						else patterns[i]=patterns[i]+"[CLOSED_HI_HAT]"+duration;
						break;
					}
				}
				if(temp.get(j).get(0)!=-1) if(j<col) j=col-1;
			}
		}
		
		public String duration(int v){
			switch(v){
			case 1:
				return "i";
			case 2:
				return "q";
			case 3:
				return "qi";
			default:
				return "h";
			}		
		}
		
	}
	
	//start functions for tabbed play
	public class TabChangeListener implements ChangeListener{
		@Override
		public void stateChanged(ChangeEvent e) {
			MusicThreads.currentTab=tabbedpanel.getSelectedIndex();		
		}
	}
	
	public class VButtonListener implements ActionListener{

		String txt ="";
		@Override
		public void actionPerformed(ActionEvent e) {
			txt = volume.getText();
			int in = Integer.valueOf(txt.toString());
			if (in>120)in=120;
			music.get(0).setVolume(in);
		}
	}
	
	public class IButtonListener implements ActionListener{
		String txt ="";
		@Override
		public void actionPerformed(ActionEvent e) {
			txt = text.getText();
			parsetext();
			MusicThreads.part=0;	
		}
		
		//put 1,2;3,4;1,3 format into {{1,2},{3,4},{1,3}}
		public void parsetext(){
			textinput.clear();
			ArrayList<Integer> e=new ArrayList<Integer>();
			for ( int i = 0 ; i < txt.length(); i++){			
				try{
					int c=Integer.parseInt(txt.charAt(i)+"");
					System.out.println("c "+c);
					e.add(c);
					
				}catch(NumberFormatException ex){
					char k=txt.charAt(i);
					if(k==';'&&e.size()!=0){
						textinput.add(e);
						e=new ArrayList<Integer>();
					}
				}
			}
		}
	}
	
	public class ShiftOneLeftListener implements ActionListener{
		
		@Override
		public void actionPerformed(ActionEvent e){
			//clickmenu = true;
			music.get(MusicThreads.currentTab).clickmenu = true;
			ShiftLeft(MusicThreads.currentTab);
			
		}
		//clickmenu = false;
		
	}
	
	public class ShiftOneRightListener implements ActionListener{
		@Override
		public void actionPerformed(ActionEvent e){
			music.get(MusicThreads.currentTab).clickmenu = true;
			ShiftRight(MusicThreads.currentTab);
			
		}
		
	}
	
	public class ShiftOneUpListener implements ActionListener{
		@Override
		public void actionPerformed(ActionEvent e){
			music.get(MusicThreads.currentTab).clickmenu = true;
			ShiftUp(MusicThreads.currentTab);
			
		}
		
	}
	
	public class ShiftOneDownListener implements ActionListener{
		@Override
		public void actionPerformed(ActionEvent e){
			music.get(MusicThreads.currentTab).clickmenu = true;
			ShiftDown(MusicThreads.currentTab);
			
		}
		
	}
	
	public class ShiftAllLeftListener implements ActionListener{
		@Override
		public void actionPerformed(ActionEvent e){
			music.get(MusicThreads.currentTab).clickmenu = true;
			for (int i = 0; i < music.size(); i++){
				//music.get(i).clickmenu = true;
				ShiftLeft(i);
			}
		}
	}
	
	public class ShiftAllRightListener implements ActionListener{
		@Override
		public void actionPerformed(ActionEvent e){
			music.get(MusicThreads.currentTab).clickmenu = true;
			for (int i = 0; i < music.size(); i++){
				//music.get(i).clickmenu = true;
				ShiftRight(i);
			}
		}
	}
	
	public class ShiftAllUpListener implements ActionListener{
		@Override
		public void actionPerformed(ActionEvent e){
			music.get(MusicThreads.currentTab).clickmenu = true;
			for (int i = 0; i < music.size(); i++){
				//music.get(i).clickmenu = true;
				ShiftUp(i);
			}
		}
	}
	
	public class ShiftAllDownListener implements ActionListener{
		@Override
		public void actionPerformed(ActionEvent e){
			music.get(MusicThreads.currentTab).clickmenu = true;
			for (int i = 0; i < music.size(); i++){
				//music.get(i).clickmenu = true;
				ShiftDown(i);
			}
		}
	}
	
	public class MousePressedListener extends MouseAdapter{
		private boolean on=false;
		
		@Override
		public void mousePressed(MouseEvent e){
			JButton btn=(JButton)e.getComponent();
			Object tmp = btn.getClientProperty("column");
			int tmpa = Integer.valueOf(tmp.toString());
			tmp = btn.getClientProperty("row");
			int tmpb = Integer.valueOf(tmp.toString());
			tmp = btn.getClientProperty("tab");
			int tmpc = Integer.valueOf(tmp.toString());
			System.out.println(btn.getX()+"     "+btn.getY());
			System.out.println("clicked column "+btn.getClientProperty("column")+", row "+btn.getClientProperty("row")+", tab"+btn.getClientProperty("tab"));
			if (btn.getBackground()==currentbuttoncolor){
				on = true;
				on=EditNote(tmpa,tmpb,on,tmpc);
				btn.setBackground(Color.DARK_GRAY);
				syncOn=false;
			}
			else{
				on = false;
				on=EditNote(tmpa,tmpb,on,tmpc);
				btn.setBackground(currentbuttoncolor);
				syncOn=true;
			}
			/*on=EditNote(tmpa,tmpb,on,tmpc);
			if(on){ btn.setBackground(currentbuttoncolor);syncOn=true;}
			else {btn.setBackground(Color.DARK_GRAY);syncOn=false;}*/
		}
		
		@Override
		public void mouseEntered(MouseEvent e){
			JButton btn=(JButton)e.getComponent();
			if (btn.getBackground()==currentbuttoncolor) on = true;
			else if (btn.getBackground()==Color.DARK_GRAY) on = false;
			if (e.getModifiers() == MouseEvent.BUTTON1_MASK&&on!=syncOn&&!music.get(MusicThreads.currentTab).clickmenu) { //when click on function menu, the button will on, later when some more function added, implement a boolean value to present it
				Object tmp = btn.getClientProperty("column");
				int tmpa = Integer.valueOf(tmp.toString());
				tmp = btn.getClientProperty("row");
				int tmpb = Integer.valueOf(tmp.toString());
				tmp = btn.getClientProperty("tab");
				int tmpc = Integer.valueOf(tmp.toString());
				//System.out.println("clicked column "+btn.getClientProperty("column")+", row "+btn.getClientProperty("row")+", tab"+btn.getClientProperty("tab"));
				on=EditNote(tmpa,tmpb,on,tmpc);
				if(on) btn.setBackground(currentbuttoncolor);
				else btn.setBackground(Color.DARK_GRAY);
			}
		}
		
		//public void returnfalse(){
		//	on = false;
		//}
	}
	
	public void ShiftLeft(int tab){
		ArrayList<Integer> storefirstcolumn = new ArrayList<Integer>();
		int k = 0;
		for (int i = 0; i < buttons.get(tab).size(); i++){
			if (buttons.get(tab).get(i).getBackground()==currentbuttoncolor&&i%16==0){
				buttons.get(tab).get(i).setBackground(Color.DARK_GRAY);
				storefirstcolumn.add(k,i);
				k++;
			}
			else if (buttons.get(tab).get(i).getBackground()==currentbuttoncolor){
				buttons.get(tab).get(i).setBackground(Color.DARK_GRAY);
				buttons.get(tab).get(i-1).setBackground(currentbuttoncolor);
			}
		}
		
		for(int i = 0; i < storefirstcolumn.size();i++ )
			buttons.get(tab).get(storefirstcolumn.get(i)+15).setBackground(currentbuttoncolor);
		
		storefirstcolumn = music.get(tab).block.get(1);
		for (int i =1; i < music.get(tab).block.size()-1; i++)
			music.get(tab).block.set(i,music.get(tab).block.get(i+1));
		music.get(tab).block.set(15,storefirstcolumn);
	
		
	}
	
	public void ShiftRight(int tab){
		ArrayList<Integer> storelastcolumn = new ArrayList<Integer>();
		int k = 0;
		for (int i = buttons.get(tab).size()-1; i >=0; i--){
			System.out.println(i%16);
			System.out.println(buttons.get(tab).get(i).getBackground());
			if (buttons.get(tab).get(i).getBackground()==currentbuttoncolor&&i%16==15){
				buttons.get(tab).get(i).setBackground(Color.DARK_GRAY);
				storelastcolumn.add(k,i);
				k++;
			}
			else if (buttons.get(tab).get(i).getBackground()==currentbuttoncolor){
				buttons.get(tab).get(i).setBackground(Color.DARK_GRAY);
				buttons.get(tab).get(i+1).setBackground(currentbuttoncolor);
			}
		}
		
		for(int i = 0; i < storelastcolumn.size();i++ )
			buttons.get(tab).get(storelastcolumn.get(i)-15).setBackground(currentbuttoncolor);
	
		storelastcolumn = music.get(tab).block.get(15);
		for (int i =14; i >0; i--)
			music.get(tab).block.set(i+1,music.get(tab).block.get(i));
		music.get(tab).block.set(1,storelastcolumn);
	}
	
	public void ShiftUp(int tab){
		ArrayList<Integer> storefirstrow = new ArrayList<Integer>();
		int k = 0;
		for(int j=0;j<buttons.get(tab).size();j++){
			if(buttons.get(tab).get(j).getBackground()==currentbuttoncolor&&j>15){
				buttons.get(tab).get(j).setBackground(Color.DARK_GRAY);
				//System.out.println(j);
				buttons.get(tab).get(j-16).setBackground(currentbuttoncolor);
			}
			else if ((buttons.get(tab).get(j).getBackground()==currentbuttoncolor&&j<16)){
				buttons.get(tab).get(j).setBackground(Color.DARK_GRAY);
				storefirstrow.add(k, j);
				k++;
				//buttons.get(MusicThreads.currentTab).get(240+j).setBackground(currentbuttoncolor);
			}
		}
		for(int j = 0; j < storefirstrow.size();j++)
			buttons.get(tab).get(240+storefirstrow.get(j)).setBackground(currentbuttoncolor);
		
		for(int j = 0; j < 16; j++){
			for(int i = 0; i < music.get(tab).block.get(j).size(); i++){
				//System.out.println(music.get(tab).block.get(j).size());
				if (music.get(tab).block.get(j).get(i)!=-1){
						
					int row = music.get(tab).block.get(j).get(i);
					//System.out.println(row);
					music.get(tab).block.get(j).set(i, (row+1)%16);
				}
			}
		}
	}
	
	public void ShiftDown(int tab){
		ArrayList<Integer> storelastrow = new ArrayList<Integer>();
		int k = 0;
		for(int j=buttons.get(tab).size()-1;j>=0;j--){
			if(buttons.get(tab).get(j).getBackground()==currentbuttoncolor&&j<240){
				buttons.get(tab).get(j).setBackground(Color.DARK_GRAY);
				//System.out.println(j);
				buttons.get(tab).get(j+16).setBackground(currentbuttoncolor);
			}
			else if ((buttons.get(tab).get(j).getBackground()==currentbuttoncolor)){
				buttons.get(tab).get(j).setBackground(Color.DARK_GRAY);
				storelastrow.add(k, j);
				k++;
				//buttons.get(MusicThreads.currentTab).get(240+j).setBackground(currentbuttoncolor);
			}
		}
		for(int j = storelastrow.size()-1; j >=0 ;j--)
			buttons.get(tab).get(storelastrow.get(j)-240).setBackground(currentbuttoncolor);
		
		for(int j = 0; j < 16; j++){
			for(int i = 0; i < music.get(tab).block.get(j).size(); i++){
				//System.out.println(music.get(tab).block.get(j).size());
				if (music.get(tab).block.get(j).get(i)!=-1){
						
					int row = music.get(tab).block.get(j).get(i);
					//System.out.println(row);
					music.get(tab).block.get(j).set(i, row+15);
				}
			}
		}
	}
	
	public void ColorChange(Color color){
		for (int i= 0; i < music.size(); i++){
			for(int j=0;j<buttons.get(i).size();j++){
				if(buttons.get(i).get(j).getBackground()==currentbuttoncolor)
					buttons.get(i).get(j).setBackground(color);
			}
		}
	}
	
	/*public ArrayList<ArrayList<JButton>> getButtons(){
		return buttons;
	}*/
	
	public ArrayList<MusicThreads> getMusicThreads(){
		return music;
	}

	
}
// test

